package io.renren.service.impl;

import com.baomidou.mybatisplus.toolkit.StringUtils;
import io.renren.common.exception.RRException;
import io.renren.config.FileServerConfig;
import io.renren.constant.AppConstant;
import io.renren.constant.PointsType;
import io.renren.dao.PersonalCenterDao;
import io.renren.entity.AppUserEntity;
import io.renren.entity.PointsResult;
import io.renren.po.UserPoints;
import io.renren.service.PersonalCenterService;
import io.renren.util.Base64Utils;
import io.renren.util.DfsUtil;
import io.renren.vo.FileServerResponse;
import io.renren.vo.RespModel;
import org.apache.http.entity.ContentType;
import org.aspectj.weaver.ast.Var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.util.*;

/**
 * Created by ThinkPad on 2018/11/29.
 */
@Service
public class PersonalCenterServiceImpl implements PersonalCenterService {

    @Autowired
    private PersonalCenterDao personalCenterDao;

    @Autowired
    private FileServerConfig fileServerConfig;

    /**
     * 查询用户积分
     *
     * @param userid
     * @return
     */
    @Override
    public PointsResult queryUserPoints(String userid) {
        return personalCenterDao.queryUserPoints(userid);
    }

    public List<Map> queryGoods() {
        return personalCenterDao.queryGoods();
    }

    public List<Map> queryPoints(String userid) {
        return personalCenterDao.queryPoints(userid);
    }

    /**
     * 根据用户操作操作用户积分
     *
     * @param userPoints
     * @return
     */
    public RespModel updateUserPointByOperation(UserPoints userPoints) {
        //查询用户是否有签到记录
        Map paramMap = new HashMap();
        paramMap.put("type", PointsType.签到.getCode());
        paramMap.put("date", LocalDate.now().toString());
        paramMap.put("userid", userPoints.getUserid());
        boolean birthDay = false;
        UserPoints userPoints1 = personalCenterDao.queryPointsLog(paramMap);
        if (userPoints1 == null && userPoints.getType().equals(PointsType.签到.getCode())) {
            //判断是否VIP生日
            birthDay = vipUserBirthDay(userPoints);
        }
        //更新用户积分
        Map<String, Object> calculate_map = operateUserPoints(userPoints);
        //查询用户积分
        PointsResult pointsResult = personalCenterDao.queryUserPoints(userPoints.getUserid());
        Map result_map = new HashMap();
        result_map.put("points", pointsResult.getPoints());
        result_map.put("vipBirthday", birthDay);
        result_map.put("signtoday", false);
        result_map.put("continuousSign", 0);
        if (userPoints1 != null) {
            result_map.put("signtoday", true);
            result_map.put("continuousSign", userPoints1.getLxqd());
        } else {
            //查询昨天是否签到
            paramMap.put("date", LocalDate.now().minusDays(1).toString());
            UserPoints userPoints2 = personalCenterDao.queryPointsLog(paramMap);
            if (userPoints2 != null && userPoints.getType().equals(PointsType.签到.getCode())) {
                result_map.put("continuousSign", userPoints2.getLxqd() + 1);
            } else if (userPoints2 != null) {
                result_map.put("continuousSign", userPoints2.getLxqd());
            } else if(userPoints.getType().equals(PointsType.签到.getCode())){
                result_map.put("signtoday", true);
            }
        }

        return new RespModel().getRespModelInstance(AppConstant.STATU_SUCCESS,
                String.format(((String) calculate_map.get("reason")), calculate_map.get("points")), result_map);
    }

    /**
     * 操作用户积分
     *
     * @param userPoints
     * @return
     */
    public Map<String, Object> operateUserPoints(UserPoints userPoints) {
        //根据不同的操作类型计算积分
        Map<String, Object> map = calculateUserPoints(userPoints);
        if ((Integer) map.get("points") != 0) {
            //更新用户积分
            map.put("userid", userPoints.getUserid());
            userPoints.setPoints(((Integer) map.get("points")));
            Integer update_count = personalCenterDao.updateUserPoints(map);
            if (null == update_count || update_count == 0) {
                //生成用户积分记录
                personalCenterDao.saveUserPoints(userPoints);
            }
            userPoints.setLxqd(((Integer) map.get("lxqd")));
            personalCenterDao.saveUserOperationLog(userPoints);
        }
        return map;
    }

    /**
     * 计算操作对用的积分和连续天数
     *
     * @param userPoints
     * @return
     */
    public Map<String, Object> calculateUserPoints(UserPoints userPoints) {
        int points = 0, lxqd = 0;

        Optional<PointsType> pointsType_Optional = Arrays.stream(PointsType.values())
                .filter(pointsType -> userPoints.getType().equals(pointsType.getCode()))
                .findFirst();
        if (pointsType_Optional.isPresent() == false) {
            throw new RRException("错误的操作类型码！");
        }
        PointsType.PointsObject pointsObject = pointsType_Optional.get().getPointsObject();
        switch (userPoints.getType()) {
            case "2001":
                System.out.println("=======判断是否签到");
                //判断是否已经签到
                UserPoints today_signUpLog = queryPointsLog(userPoints, LocalDate.now().toString());
                if (today_signUpLog == null) { //没有签到
                    //判断当前是否当月的第一天
                    if (1 == LocalDate.now().getDayOfMonth()) {
                        points = pointsObject.getPoints();
                        lxqd = 1;
                    } else {
                        //查询昨天是否签到
                        UserPoints yesterday_signUpLog = queryPointsLog(userPoints, LocalDate.now().minusDays(1).toString());
                        if (yesterday_signUpLog == null) {
                            points = pointsObject.getPoints();
                            lxqd = 1;
                        } else {
                            int yesterday_points = yesterday_signUpLog.getPoints();
                            if (yesterday_points < 20) {
                                points = yesterday_points + pointsObject.getPoints();
                                lxqd++;
                            } else {
                                points = 20;
                                lxqd++;
                            }
                        }
                        //判断签到是否连续一个月,满月赠送100积分
                        if (lxqd == LocalDate.now().lengthOfMonth()) {
                            HashMap<Object, Object> paramMap = new HashMap<>();
                            paramMap.put("userid", userPoints.getUserid());
                            paramMap.put("points", pointsObject.getPoints());
                            personalCenterDao.updateUserPoints(paramMap);
                        }
                    }
                }
                break;
            case "3001":
                //查询阅读积分总和
                int pointsSum = queryPointsSum(userPoints, LocalDate.now().toString());
                if (pointsSum < 20) {
                    points = pointsObject.getPoints();
                }
                break;
            case "4004": //4004与4001 处理方式相同，使用4001代码
            case "4001":
                int pointsSum1 = queryPointsSum(userPoints, LocalDate.now().toString());
                if (pointsSum1 < 100) {
                    points = pointsObject.getPoints();
                }
                break;
            case "4002":
                int pointsSum2 = queryPointsSum(userPoints, LocalDate.now().toString());
                if (pointsSum2 < 30) {
                    points = pointsObject.getPoints();
                }
                break;
            case "4003":
                int pointsSum3 = queryPointsSum(userPoints, LocalDate.now().toString());
                if (pointsSum3 < 50) {
                    points = pointsObject.getPoints();
                }
                break;
            default:
                points = pointsObject.getPoints();
                break;
        }
        Map result_map = new HashMap();
        result_map.put("points", points);
        result_map.put("lxqd", lxqd);
        result_map.put("reason", pointsObject.getPointsName());
        return result_map;
    }

    /**
     * 查询用户某一操作类型指定日期的积分
     *
     * @param userPoints
     * @param date
     * @return
     */
    public UserPoints queryPointsLog(UserPoints userPoints, String date) {
        HashMap<Object, Object> paramMap = new HashMap<>();
        paramMap.put("userid", userPoints.getUserid());
        paramMap.put("type", userPoints.getType());
        paramMap.put("date", date);
        return personalCenterDao.queryPointsLog(paramMap);
    }

    /**
     * 查询某一操作指定日期积分总和
     *
     * @param userPoints
     * @param date
     * @return
     */
    public int queryPointsSum(UserPoints userPoints, String date) {
        HashMap<Object, Object> paramMap = new HashMap<>();
        paramMap.put("userid", userPoints.getUserid());
        paramMap.put("type", userPoints.getType());
        paramMap.put("date", date);
        return personalCenterDao.queryPointsSum(paramMap);
    }

    /**
     * 判断今天是否为VIP用户生日
     *
     * @param userPoints
     */
    public boolean vipUserBirthDay(UserPoints userPoints) {
        boolean isBirthDay = false;
        Map map = personalCenterDao.queryAppUserInfo(userPoints.getUserid());
        if (map != null && map.containsKey("sfzh")) {
            String sfzh = (String) map.get("sfzh");
            int monthValue = LocalDate.now().getMonthValue();
            int dayOfMonth = LocalDate.now().getDayOfMonth();
            String birthday = (monthValue < 10 ? "0" + monthValue : "" + monthValue) + (dayOfMonth < 10 ? "0" + dayOfMonth : "" + dayOfMonth);
            if (StringUtils.isNotEmpty(sfzh) && sfzh.substring(10, 14).equals(birthday)) {
                Map param = new HashMap();
                param.put("userid", userPoints.getUserid());
                param.put("type", PointsType.VIP用户生日送积分.getCode());
                param.put("points", PointsType.VIP用户生日送积分.getPointsObject().getPoints());
                Integer update_count = personalCenterDao.updateUserPoints(param);
                if (update_count == null || update_count == 0) {
                    userPoints.setPoints(PointsType.VIP用户生日送积分.getPointsObject().getPoints());
                    personalCenterDao.saveUserPoints(userPoints);
                }
                userPoints.setPoints(PointsType.VIP用户生日送积分.getPointsObject().getPoints());
                userPoints.setType(PointsType.VIP用户生日送积分.getCode());
                personalCenterDao.saveUserOperationLog(userPoints);
                isBirthDay = true;
            }
        }
        return isBirthDay;
    }


    @Override
    public RespModel upgradeVIp(AppUserEntity appUserEntity) {
        //判断用户驾驶证是否与身份证匹配
        // TODO 验证用户驾驶证号，目前缺少6合1接口
        String s = uploadFile(appUserEntity.getScanUrlZ(), appUserEntity.getUserid());
        String s1 = uploadFile(appUserEntity.getScanUrlF(), appUserEntity.getUserid());
        if(s==null || s1 ==null){
            return new RespModel().getRespModelInstance(AppConstant.STATU_FAIL, "身份证照片格式不正确无法上传", null);
        }
        appUserEntity.setScanUrlZ(s);
        appUserEntity.setScanUrlF(s1);
        appUserEntity.setId(UUID.randomUUID().toString());
        //查询用户是否已存在
        Map map = personalCenterDao.queryAppUserInfo(appUserEntity.getUserid());
        if(CollectionUtils.isEmpty(map)){
            personalCenterDao.insertAppUser(appUserEntity);
        }else{
            personalCenterDao.updateAppUser(appUserEntity);
        }
        return new RespModel().getRespModelInstance(AppConstant.STATU_SUCCESS, "", null);
    }

    /**
     * 上传文件身份证照片
     * @param base64ImageStr
     * @param userid
     * @return
     */
    public String uploadFile(String base64ImageStr, String userid){
        String result_str = null;
        //上传用户身份证照片（base64字符串）
        String format_imageStr = Base64Utils.base64Format(base64ImageStr).replace("data:image/png;base64,","");
        try{
            byte[] bytes = Base64Utils.GenerateImageFromBase64(format_imageStr);
            if(bytes != null){
                FileServerResponse fileServerResponse = DfsUtil.uploadFileByBinary(userid + "sfz.png", bytes, ContentType.IMAGE_PNG, fileServerConfig.getImageUploadUrl());
                result_str = fileServerResponse.getRealHttpUrl();
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return result_str;
    }

    public Map queryAppUserInfo(String userid){
        return personalCenterDao.queryAppUserInfo(userid);
    }
}
